Skip to content

fix(resume-checker): show real copy instead of API error codes, and start a test suite - #32

Merged
lautaropaske merged 3 commits into
mainfrom
fix/resume-checker-error-copy
Aug 31, 2026
Merged

lautaropaske merged 3 commits into
mainfrom
fix/resume-checker-error-copy

Conversation

@lautaropaske

Copy link
Copy Markdown
Contributor

Supersedes #12, which was opened against a base from April and whose route changes have since been overtaken by a8e92c1. Rewritten on top of current main.

What changed

The review page showed users raw strings from the API. review.tsx called res.json() on every failed response and rendered the result straight into the red ErrorBadge (which prints error.message). Two live failure modes:

  • Non-JSON bodies threw. The resume dropzone has no size cap, so any PDF over Vercel's 4.5MB function payload limit gets a plain-text 413 from the platform before the route runs — res.json() threw, and the badge showed Unexpected token 'R'.... Gateway timeouts on the 300s route behaved the same way.
  • Error codes leaked as copy. Since a8e92c1 the route answers with stable codes, so the badge showed users the literal strings MissingURL and GradingError.

getErrorMessage in src/resume-checker/utils.ts maps the codes the route can answer with to Spanish copy, gives 413 its own message, and falls back to the generic one otherwise. Nothing from the response body reaches the badge — deliberately no raw-text fallback, since that just re-leaks a 504 HTML page into the UI.

Test suite. vitest was already a devDependency with nothing to run. Added vitest.config.ts, a test script, and 15 tests: the /api/grade status/code contract (4xx for crawler GETs and bad uploads, no raw message on the 500 path) and the error mapping. Tests live in tests/ rather than beside the route — anything under src/pages is a page, so a co-located grade.test.ts would be served at /api/grade.test and fail the build for want of a default export.

CI. Nothing ran the suite. Lint + typecheck + test on every PR; build stays out since Vercel already builds each one.

What #12 had that this drops

Its grade.ts diff is superseded by a8e92c1, which does the same 4xx normalization and goes further by returning a stable GradingError instead of e.message — #12 still did sendJsonError(res, 500, e.message), so rebasing it would have reintroduced the leak. Also dropped its ~150 lines of tests that only exercised its own mock helpers, and its export default function GradeRouteTestHarness() {} workaround, which the tests/ layout makes unnecessary.

#12's "known issue" (React 19.2.0 vs 19.2.3 breaking the build) no longer applies — both are pinned at 19.2.3.

Testing

  • bun run test — 15/15 pass. Mutation-checked: reverting the 405 guard or the GradingError code fails 2 tests.
  • bunx tsc --noEmit, bun run lint, bunx prettier --check — clean.
  • bun run build — passes; /api/grade.test correctly absent from the route list.

🤖 Generated with Claude Code

https://claude.ai/code/session_01EeCD8BnUFcRVxrdxKfHnKE

lautaropaske and others added 3 commits August 31, 2026 16:00
The review page called `res.json()` on every failed response. Two problems,
both visible to users in the red `ErrorBadge`, which renders `error.message`
verbatim:

- A non-JSON body threw inside the mutation, so the badge showed the parse
  error ("Unexpected token 'R'..."). The dropzone has no size cap, so any
  resume over Vercel's 4.5MB function payload limit gets a plain-text 413
  from the platform and hits this. Gateway timeouts on a 300s route do too.
- Since a8e92c1 the route answers with stable codes, so the badge showed
  users the literal strings "MissingURL" and "GradingError".

`getErrorMessage` maps the codes the route can answer with to Spanish copy,
gives 413 its own message, and falls back to the generic one for everything
else. Nothing from the response body reaches the badge any more.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EeCD8BnUFcRVxrdxKfHnKE
vitest was already a devDependency with nothing to run. Add the config, a
`test` script, and the first tests: the grade route's status/code contract
(4xx for crawler GETs and bad uploads, no raw message on the 500 path) and
the resume-checker error mapping.

Tests live in `tests/` rather than beside the route because anything under
`src/pages` is a page — a co-located `grade.test.ts` would be served at
/api/grade.test and fail the build for want of a default export.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EeCD8BnUFcRVxrdxKfHnKE
Nothing ran the suite. Build stays out of it — Vercel already builds every
PR.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EeCD8BnUFcRVxrdxKfHnKE
@vercel

vercel Bot commented Aug 31, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
open-silver Ready Ready Preview Aug 31, 2026 7:03pm

Request Review

@lautaropaske
lautaropaske merged commit 9013deb into main Aug 31, 2026
3 checks passed
@lautaropaske
lautaropaske deleted the fix/resume-checker-error-copy branch August 31, 2026 19:37

This branch was successfully deployed

1 active deployment
Preview — e3dab609 Deployed Aug 31, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant